package com.tony.glyphhackhelper;

/**
 * Created by tony on 8/11/16.
 */

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;

import java.nio.ByteBuffer;

import wei.mark.standout.StandOutWindow;
import wei.mark.standout.constants.StandOutFlags;

public class ScreenCaptureService extends StandOutWindow {
    private static final String TAG = "ScreenCaptureService";

    private MediaProjection mMediaProjection = null;
    private VirtualDisplay mVirtualDisplay = null;
    private ImageReader mImageReader = null;

    private View mFloatLayout = null;

    public static int mResultCode = 0;
    public static Intent mResultData = null;
    public static MediaProjectionManager mMediaProjectionManager1 = null;


    private WindowManager mWindowManager1 = null;
    private int windowWidth = 0;
    private int windowHeight = 0;
    private DisplayMetrics metrics = null;
    private int mScreenDensity = 0;

    private Button mCaptureButton;
    private Button mClearButton;
    private Button mStartButton;
    private ImageView[] mImageViews = new ImageView[5];
    private int imageIndex = 0;
    private boolean isServiceStarted = false;
    private MODE currentMode = MODE.FOUR_PICTURE;
    private int imageNum = 4;
    private boolean imageCleared = true;

    private enum MODE{
        FOUR_PICTURE,
        FIVE_PICTURE
    }

    @Override
    public void onCreate()
    {
        // TODO Auto-generated method stub
        super.onCreate();

        createVirtualEnvironment();
        currentMode = MODE.FOUR_PICTURE;
        imageNum = 4;
        imageCleared = true;

    }

    /*
        @Override
        public void onDestroy() {
            stopVirtual();
            super.onDestroy();
        }
        */
    @Override
    public boolean onClose(int id, wei.mark.standout.ui.Window window) {
        stopVirtual();
        return false;
    }

    @Override
    public String getAppName() {
        return getResources().getString(R.string.app_name);
    }

    @Override
    public int getAppIcon() {
        return android.R.drawable.ic_menu_close_clear_cancel;
    }

    @Override
    public void createAndAttachView(int id, FrameLayout frame) {
        // create a new layout from body.xml
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        mFloatLayout =  inflater.inflate(R.layout.activity_screen_capture, frame, true);

        //mStartButton = (Button)mFloatLayout.findViewById(R.id.start_button);
        mCaptureButton = (Button)mFloatLayout.findViewById(R.id.capture_button);
        mClearButton = (Button)mFloatLayout.findViewById(R.id.clear_button);
        mImageViews[0] = (ImageView)mFloatLayout.findViewById(R.id.image_view_1);
        mImageViews[1] = (ImageView)mFloatLayout.findViewById(R.id.image_view_2);
        mImageViews[2] = (ImageView)mFloatLayout.findViewById(R.id.image_view_3);
        mImageViews[3] = (ImageView)mFloatLayout.findViewById(R.id.image_view_4);
        mImageViews[4] = (ImageView)mFloatLayout.findViewById(R.id.image_view_5);
        mImageViews[4].setVisibility(View.GONE);



        /*
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isServiceStarted)
                {
                    stopVirtual();
                    mStartButton.setText(getResources().getString(R.string.start));
                    isServiceStarted = false;
                }
                else {
                    startVirtual();
                    mStartButton.setText(getResources().getString(R.string.stop));
                    isServiceStarted = true;
                }
            }
        });

    */
        mCaptureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startCapture();
            }
        });

        mClearButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!imageCleared) {
                    clearImage();
                }
                else {
                    switchMode();
                }
                setClearButtonText();
            }
        });

        Handler handler1 = new Handler();
        handler1.postDelayed(new Runnable() {
            public void run() {
                //start virtual
                startVirtual();
            }
        }, 1000);



    }
    private void setClearButtonText()
    {
        if (currentMode == MODE.FOUR_PICTURE)
        {
            mClearButton.setText(getResources().getString(R.string.mode_4));
        }
        else
        {
            mClearButton.setText(getResources().getString(R.string.mode_5));
        }
    }

    private void switchMode()
    {
        if (currentMode == MODE.FOUR_PICTURE)
        {
            Log.i(TAG, "switch to five mode");
            currentMode = MODE.FIVE_PICTURE;
            mImageViews[4].setVisibility(View.VISIBLE);
            imageNum = 5;
        }
        else
        {
            Log.i(TAG, "switch to four mode");
            currentMode = MODE.FOUR_PICTURE;
            mImageViews[4].setVisibility(View.GONE);
            imageNum = 4;
        }
    }

    // the window will be centered
    @Override
    public StandOutLayoutParams getParams(int id, wei.mark.standout.ui.Window window) {
        return new StandOutLayoutParams(id, windowWidth, windowHeight*4/25,
                StandOutLayoutParams.CENTER, StandOutLayoutParams.TOP);
    }

    // move the window by dragging the view
    @Override
    public int getFlags(int id) {
        return super.getFlags(id) | StandOutFlags.FLAG_BODY_MOVE_ENABLE
                | StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE;
    }

    @Override
    public String getPersistentNotificationMessage(int id) {
        return getResources().getString(R.string.click_to_close)+ "\"" +
                getResources().getString(R.string.app_name) + "\"";
    }

    @Override
    public Intent getPersistentNotificationIntent(int id) {
        return StandOutWindow.getCloseIntent(this, ScreenCaptureService.class, id);
    }


    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void startVirtual(){
        if (mMediaProjection != null) {
            Log.i(TAG, "want to display virtual");
            virtualDisplay();
        } else {
            Log.i(TAG, "start screen capture intent");
            setUpMediaProjection();
            virtualDisplay();
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void stopVirtual() {
        if (mVirtualDisplay == null) {
            return;
        }
        mVirtualDisplay.release();
        mVirtualDisplay = null;
        Log.i(TAG,"virtual display stopped");
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void createVirtualEnvironment(){

        mMediaProjectionManager1 = (MediaProjectionManager)getApplication().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        mWindowManager1 = (WindowManager)getApplication().getSystemService(Context.WINDOW_SERVICE);
        windowWidth = mWindowManager1.getDefaultDisplay().getWidth();
        windowHeight = mWindowManager1.getDefaultDisplay().getHeight();
        metrics = new DisplayMetrics();
        mWindowManager1.getDefaultDisplay().getMetrics(metrics);
        mScreenDensity = metrics.densityDpi;
        mImageReader = ImageReader.newInstance(windowWidth, windowHeight, 0x1, 2); //ImageFormat.RGB_565
        Log.i(TAG, "prepared the virtual environment");
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void virtualDisplay(){
        mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
                windowWidth, windowHeight, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);
        Log.i(TAG, "virtual displayed");
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void setUpMediaProjection(){
        mResultData = ((ScreenCaptureApplication)getApplication()).getIntent();
        mResultCode = ((ScreenCaptureApplication)getApplication()).getResult();
        mMediaProjectionManager1 = ((ScreenCaptureApplication)getApplication()).getMediaProjectionManager();
        mMediaProjection = mMediaProjectionManager1.getMediaProjection(ScreenCaptureActivity.RESULT_OK, mResultData);
    }


    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void startCapture(){
        Image image = mImageReader.acquireLatestImage();
        if (image == null)
        {
            Log.e(TAG, "Can not acquire image!");
            return;
        }
        int width = image.getWidth();
        int height = image.getHeight();
        Log.i(TAG, "bitmap width = " + width + " height = " + height);
        final Image.Plane[] planes = image.getPlanes();
        final ByteBuffer buffer = planes[0].getBuffer();
        int pixelStride = planes[0].getPixelStride();
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * width;
        Bitmap bitmap = Bitmap.createBitmap(width+rowPadding/pixelStride, height, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);
        int posY = mScreenDensity * 600 / 480;
        bitmap = Bitmap.createBitmap(bitmap, 0, posY, width, height-posY);
        image.close();

        if(bitmap != null) {
            imageCleared = false;
            mClearButton.setText(getResources().getString(R.string.clear));
            mImageViews[imageIndex].setImageBitmap(bitmap);
            imageIndex++;
            if (imageIndex >= imageNum) {
                imageIndex = 0;
            }
        }
    }

    private void clearImage() {
        imageIndex = 0;
        imageCleared = true;
        for(int i = 0; i < imageNum; i++)
        {
            mImageViews[i].setImageBitmap(null);
        }
    }
}
